#ifndef COBJECTPOLL_H
#define COBJECTPOLL_H

#include <iostream>
#include <vector>
#include "Common.h"

template<class T>
class ObjectPool
{
public:
	T* New();

	void Delete(T* obj);
private:
	char*  m_memory    = nullptr; //指向大块内存，char是一个字节，好切分内存
	size_t remainBytes = 0;		  //大块内存中剩余数
	void*  m_freeList  = nullptr; //管理还回来的内存(链表)的头指针
};


template<class T>
T* ObjectPool<T>::New()
{
	T* obj = nullptr;
	if (m_freeList)
	{
		//优先把还回来的内存再次重复利用
		void* next = (*(void**)m_freeList);  //头删
		obj = (T*)m_freeList;
		m_freeList = next;
	}
	else
	{
		//剩余内存不够一个对象大小时，重新开块大内存
		if (remainBytes < sizeof(T))
		{
			remainBytes = 128 * 1024; //128 k
			m_memory = (char*)SystemAlloc(remainBytes >> 13);  
			if (m_memory == nullptr)
			{
				throw std::bad_alloc();
			}
		}

		obj = (T*)m_memory;
		size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
		m_memory += objSize;
		remainBytes -= objSize;


		//在已有空间初始化T对象，并调用T的构造函数
		new(obj)T;

		return obj;
	}

	return nullptr;
}

template<class T>
void ObjectPool<T>::Delete(T* obj)
{
	//显示调用析构函数清理对象
	obj->~T();

	if (m_freeList == nullptr)
	{
		m_freeList = obj;
		*(void**)m_freeList = nullptr;
	}
	else
	{
		//头插
		*(void**)obj = m_freeList;
		m_freeList = obj;
	}
}

#endif // !COBJECTPOLL_H
